require "3rd/pblua/login_pb"
require "3rd/pbc/protobuf"
local lpeg = require "lpeg"
local json = require "cjson"
local util = require "3rd/cjson/util"
local sproto = require "3rd/sproto/sproto"
local core = require "sproto.core"
local print_r = require "3rd/sproto/print_r"

require "Logic/LuaClass"
require "Logic/CtrlManager"
require "Logic/ResourcesLoader"
require "Common/functions"
require "Common/define"
require "Controller/PromptCtrl"
require "WebSocket/MessageFactory"
require "WebSocket/MsgObserver"
Event = require "events"
require "Logic/GameConfig"
require "Logic/WSKGameMemory"
require "Logic/GameUtil"
require "Logic/CardType"
--管理器--
Game = {
    click = false,
    frameRate = 30,
    reporter = true,
    wxOn = false,
    needClearToken = true,
    switchConnect = true,
    serverAddress = {
        address = "ws://192.168.1.91:8030/g",
        --WXAppLoginCallBackUrl = "http://ylj.guojin123.net:8080/appWeixinLogin.json",
        --address1 = "ws://192.168.1.53:8010/g",
        --address2 = "ws://192.168.1.54:8010/g",
    }
}
local this = Game
--框架初始化完成，开始游戏初始化--
function Game.OnInitOK()
    AppConst.WebSocketAddress = this.serverAddress.address
    --AppConst.WXAppLoginCallBackUrl = this.serverAddress.WXAppLoginCallBackUrl
    --连接网络
    -- if (not this. switchConnect) then
    Network.SendConnect()
    -- end
    --设置帧率
    Application.targetFrameRate = this.frameRate
    --注册LuaView--
    this.InitViewPanels()
    --初始化ctrl
    CtrlManager.Init()
    --启动全局监听
    MsgObserver.Init()
    --注册update
    UpdateBeat:Add(this.Update, self)
    --设置全局视听
    this.SetGlobalObj()
    --初始化等待面板
    --PopupWaitCtrl.Init()
    --加载登录场景
    LoadingSceneCtrl.LoadScene(LoadingSceneCtrl.LoginScene.sceneName)

    logWarn('LuaFramework InitOK--->>>');

    -- this.test_class_func();
    -- this.test_pblua_func();
    -- this.test_cjson_func();
    -- this.test_pbc_func();
    -- this.test_lpeg_func();
    -- this.test_sproto_func();
    --coroutine.start(this.test_coroutine);

    --local ctrl = CtrlManager.GetCtrl(CtrlNames.Prompt);
    --if ctrl ~= nil and AppConst.ExampleMode == 1 then
    --    ctrl:Awake();
    --end
end
function this.SetGlobalObj()
    local obj1 = GameObject.Find("PopupCanvas")
    local obj2 = GameObject.Find("AudioAndVisual")
    UnityEngine.Object.DontDestroyOnLoad(obj1)
    UnityEngine.Object.DontDestroyOnLoad(obj2)
    if (not this.reporter) then
        local obj3 = GameObject.Find("Reporter")
        UnityEngine.Object.Destroy(obj3)
    end
end
function Game.InitViewPanels()
    for i, v in pairs(PanelNames) do
        require("View/" .. v)
    end
end
function this.Update()
    if Input.GetKey(KeyCode.Escape) then
        local ctrl = CtrlManager.GetCtrl(CtrlNames.PopupConfirmationBox)
        ctrl.CreatePanel(function()
            Application.Quit()
        end, "消息", "确定要退出游戏？", false)
    end
end

--测试协同--
function Game.test_coroutine()
    logWarn("1111");
    coroutine.wait(1);
    logWarn("2222");

    local www = WWW("http://bbs.ulua.org/readme.txt");
    coroutine.www(www);
    logWarn(www.text);
end

--测试sproto--
function Game.test_sproto_func()
    logWarn("test_sproto_func-------->>");
    local sp = sproto.parse [[
    .Person {
        name 0 : string
        id 1 : integer
        email 2 : string

        .PhoneNumber {
            number 0 : string
            type 1 : integer
        }

        phone 3 : *PhoneNumber
    }

    .AddressBook {
        person 0 : *Person(id)
        others 1 : *Person
    }
    ]]

    local ab = {
        person = {
            [10000] = {
                name = "Alice",
                id = 10000,
                phone = {
                    { number = "123456789", type = 1 },
                    { number = "87654321", type = 2 },
                }
            },
            [20000] = {
                name = "Bob",
                id = 20000,
                phone = {
                    { number = "01234567890", type = 3 },
                }
            }
        },
        others = {
            {
                name = "Carol",
                id = 30000,
                phone = {
                    { number = "9876543210" },
                }
            },
        }
    }
    local code = sp:encode("AddressBook", ab)
    local addr = sp:decode("AddressBook", code)
    print_r(addr)
end

--测试lpeg--
function Game.test_lpeg_func()
    logWarn("test_lpeg_func-------->>");
    -- matches a word followed by end-of-string
    local p = lpeg.R "az" ^ 1 * -1

    print(p:match("hello"))        --> 6
    print(lpeg.match(p, "hello"))  --> 6
    print(p:match("1 hello"))      --> nil
end

--测试lua类--
function Game.test_class_func()
    LuaClass:New(10, 20):test();
end

--测试pblua--
function Game.test_pblua_func()
    local login = login_pb.LoginRequest();
    login.id = 2000;
    login.name = 'game';
    login.email = 'jarjin@163.com';

    local msg = login:SerializeToString();
    LuaHelper.OnCallLuaFunc(msg, this.OnPbluaCall);
end

--pblua callback--
function Game.OnPbluaCall(data)
    local msg = login_pb.LoginRequest();
    msg:ParseFromString(data);
    print(msg);
    print(msg.id .. ' ' .. msg.name);
end

--测试pbc--
function Game.test_pbc_func()
    local path = Util.DataPath .. "lua/3rd/pbc/addressbook.pb";
    log('io.open--->>>' .. path);

    local addr = io.open(path, "rb")
    local buffer = addr:read "*a"
    addr:close()
    protobuf.register(buffer)

    local addressbook = {
        name = "Alice",
        id = 12345,
        phone = {
            { number = "1301234567" },
            { number = "87654321", type = "WORK" },
        }
    }
    local code = protobuf.encode("tutorial.Person", addressbook)
    LuaHelper.OnCallLuaFunc(code, this.OnPbcCall)
end

--pbc callback--
function Game.OnPbcCall(data)
    local path = Util.DataPath .. "lua/3rd/pbc/addressbook.pb";

    local addr = io.open(path, "rb")
    local buffer = addr:read "*a"
    addr:close()
    protobuf.register(buffer)
    local decode = protobuf.decode("tutorial.Person", data)

    print(decode.name)
    print(decode.id)
    for _, v in ipairs(decode.phone) do
        print("\t" .. v.number, v.type)
    end
end

--测试cjson--
function Game.test_cjson_func()
    local path = Util.DataPath .. "lua/3rd/cjson/example2.json";
    local text = util.file_load(path);
    LuaHelper.OnJsonCallFunc(text, this.OnJsonCall);
end

--cjson callback--
function Game.OnJsonCall(data)
    local obj = json.decode(data);
    print(obj['menu']['id']);
end

--销毁--
function Game.OnDestroy()
    --logWarn('OnDestroy--->>>');
end
